﻿using System;
using System.Collections.Generic;
using System.Windows.Browser;
using Facebook;
using QuizzMe.Model;
using QuizzMe.QuizzServiceRef;

namespace QuizzMe.Helpers
{
    /// <summary>
    /// Helper for user authentification handling
    /// </summary>
    public class AuthHelper : Singleton<AuthHelper>
    {
        public static string AppId = "134286143310642";
        public static string[] RequestedFbPermissions = new[] { "user_about_me", "" };

        private ExtendedUser _user;

        /// <summary>
        /// Current logged user
        /// </summary>
        public ExtendedUser CurrentUser
        {
            get { return _user; }
        }

        /// <summary>
        /// FacebookClient instance
        /// </summary>
        public Fb FacebookClient
        {
            get; private set;
        }

        public event Action OnGetParams;

        private Dictionary<string, string> _params;
        public Dictionary<string, string> Params
        {
            get { return _params; }
            set
            {
                _params = value;
                if (OnGetParams != null) OnGetParams();
            }
        }

        private readonly QuizzServiceClient _client = new QuizzServiceClient();
        private Action<ExtendedUser> _onUserResfreshAction;
        private IDictionary<string, object> _values;
        private Action<ExtendedUser> _onUserConnected;
        

        public event Action<ExtendedUser> OnUserConnected;
        
        private void InvokeOnUserConnected(ExtendedUser user)
        {
            Action<ExtendedUser> handler = OnUserConnected;
            if (handler != null) handler(user);
        }

        /// <summary>
        /// Try to log in a user from his facebookId
        /// </summary>
        public ExtendedUser Login(string fbuid, IDictionary<string, object> values, Action<ExtendedUser> onConnected = null)
        {
            _user = null;
            _values = values;
            _onUserConnected = onConnected;

            try
            {
                _client.GetUserByFbUidCompleted += OnGetUserByFbUidCompleted;
                OnUserConnected += onConnected;
                _client.GetUserByFbUidAsync(fbuid, (string) _values["name"]);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
            return _user;
        }

        private void OnGetUserByFbUidCompleted(object o, GetUserByFbUidCompletedEventArgs e)
        {
            _client.GetUserByFbUidCompleted -= OnGetUserByFbUidCompleted;
            
            _user = new ExtendedUser(e.Result, _values);
            InvokeOnUserConnected(_user);
            OnUserConnected -= _onUserConnected;
        }

        /// <summary>
        /// Refresh the user data (like avatar, rank, ...)
        /// </summary>
        /// <param name="onRefreshed"></param>
        public void RefreshUser(Action<ExtendedUser> onRefreshed = null)
        {
            _onUserResfreshAction = onRefreshed;
            try
            {
                _client.GetUserByFbUidCompleted += RefreshUserInternalProcess;
                _client.GetUserByFbUidAsync(_user.User.fbId, null);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }

        private void RefreshUserInternalProcess(object o, GetUserByFbUidCompletedEventArgs e)
        {
            _user.User = e.Result;

            if (_onUserResfreshAction != null)
                _onUserResfreshAction(_user);

            _client.GetUserByFbUidCompleted -= RefreshUserInternalProcess;
        }

        public void Logout()
        {
            _user = null;
        }

        public void SetFacebookClient(FacebookClient client)
        {
            FacebookClient = new Fb(client);
        }

        public const string SlfbloginUrl = @"http://localhost/QuizzService/slfbinbrowserlogin.aspx";

        #region Methods that call the Fb-Js API
        public static void LoginToFbViaJs()
        {
            
            var loginParameters = new Dictionary<string, object>
                                      {
                                          { "display", "popup" },
                                          { "response_type", "code" } // make it code and not access token for security reasons.
                                      };


            var loginUrl = FacebookOAuthClient.GetLoginUrl(AppId, new Uri(SlfbloginUrl),
                                                           RequestedFbPermissions, loginParameters);

            // don't make the response_type = token
            // coz it will be saved in the browser's history.
            // so others might hack it.
            // rather call ExchangeCodeForAccessToken to get access token in server side.
            // we need to this in server side and not in this silverlight app
            // so that the app secret doesn't get exposed to the client in case someone
            // reverse engineers this silverlight app.
            HtmlPage.Window.Eval(String.Format("fbLogin('{0}')", loginUrl));
        }
        #endregion Methods that call the Fb-Js API
    }
}
